import serial
from PyQt5 import QtCore


class AsyncSerialPort(QtCore.QThread):
    def __init__(self, name, rate, receiver):
        """
        异步串口通信类，一个串口一条线程，使用QThread实现,不使用asyncio
        :param name: 串口名，如：COM1
        :param rate: 波特率，如：115200
        :param receiver: 数据接收器
        """
        super().__init__()
        self.name = name
        self.rate = rate
        self.is_run = False
        self.receiver = receiver

    def open(self):
        if self.is_run:
            return False
        try:
            self.serial = serial.Serial(port=self.name, baudrate=self.rate, timeout=1)
        except serial.SerialException as err:
            print("打开串口失败:", err)
            return False

        self.is_run = True
        self.start()
        return True

    def write(self, data: bytes):
        if not self.is_run:
            return False
        try:
            self.serial.write(data)
        except serial.PortNotOpenError:  # 串口未打开
            return False
        except TypeError:  # 数据类型错误
            return False
        return True

    def close(self):
        if self.is_run:
            self.is_run = False
            self.serial.close()

    def run(self) -> None:
        while self.is_run:
            data = self.serial.read_all()
            if len(data) > 0:
                self.receiver(data)  # 通过回调接口将数据传递给上层应用
